<template>
  <div>
    <!-- 行内搜素框以及功能按钮 -->
    <el-form :inline="true" class="demo-form-inline">
      <!-- 输入框 -->
      <el-form-item>
        <!-- 拥有一个清除的小按钮 使用的属性就是clearable属性 -->
        <el-input
          v-model="searchForm.name"
          placeholder="名称"
          clearable
          size="large"
        />
      </el-form-item>
      <!-- 搜索按钮 -->
      <el-form-item>
        <el-button size="large" @click="getRoleList">搜索</el-button>
      </el-form-item>
      <!-- 新增按钮 -->
      <el-form-item>
        <el-button
          type="primary"
          size="large"
          @click="centerDialogVisible = true"
          >新增</el-button
        >
      </el-form-item>
      <!-- 删除按钮 -->
      <el-form-item>
        <!-- 气泡式弹出提示框 点击事件是confirm-->
        <el-popconfirm
          title="确定批量删除选中项？"
          confirm-button-text="确认"
          cancel-button-text="取消"
          @confirm="deleteHandle(null)"
        >
          <template #reference>
            <!-- 删除按钮是否能用 定义一个状态值给disabled，批量勾选中后实现可用效果 -->
            <el-button type="danger" size="large" :disabled="delBtuStatu"
              >批量删除</el-button
            >
          </template>
        </el-popconfirm>
      </el-form-item>
    </el-form>

    <!-- 数据展示的表格 -->
    <el-table
      ref="multipleTableRef"
      :data="tableData"
      style="width: 100%"
      @selection-change="handleSelectionChange"
      stripe
      border
    >
      <!-- 选择框 -->
      <el-table-column type="selection" width="55" />
      <!-- 数据列 -->
      <el-table-column prop="name" label="名称" width="120"></el-table-column>
      <el-table-column
        prop="code"
        label="唯一编码"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column
        prop="remark"
        label="描述"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column property="statu" label="状态">
        <!-- 行内插槽 -->

        <template #default="scope">
          <el-tag :type="scope.row.statu === 1 ? 'success' : 'danger'">{{
            scope.row.statu === 1 ? "启用" : "禁用"
          }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="operate" label="操作">
        <!-- 行内插槽定义操作按钮 -->

        <template #default="scope">
          <el-button type="text" @click="permHandle(scope.row.id)"
            >分配权限</el-button
          >
          <!-- 分割线 -->
          <el-divider direction="vertical"></el-divider>
          <el-button type="text" @click="editHandle(scope.row.id)"
            >编辑</el-button
          >
          <!-- 分割线 -->
          <el-divider direction="vertical"></el-divider>
          <!-- 气泡式弹出提示框 点击事件是confirm-->
          <el-popconfirm
            title="确定删除该项？"
            confirm-button-text="确认"
            cancel-button-text="取消"
            @confirm="deleteHandle(scope.row.id)"
          >
            <template #reference>
              <el-button type="text">删除</el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 同时汉化 -->
    <el-config-provider :locale="zhCn">
      <!-- pageSizes下拉后选择每一页数据有多少条 -->
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        layout="total, sizes, prev, pager, next, jumper"
        :page-sizes="[10, 20, 50, 100]"
        :current-page="current"
        :page-size="size"
        :total="total"
      >
      </el-pagination>
    </el-config-provider>

    <!-- 新增弹窗 -->
    <el-dialog
      v-model="centerDialogVisible"
      title="新增"
      width="600px"
      align-center
      :before-close="handleClose"
    >
      <!-- 弹窗内容 -->
      <el-form
        ref="editFormRef"
        :model="editForm"
        :rules="rules"
        label-width="100px"
        class="demo-editForm"
        :size="formSize"
        status-icon
      >
        <el-form-item label="角色名称" prop="name" label-width="100px">
          <el-input v-model="editForm.name" autocomplete="off" />
        </el-form-item>
        <el-form-item label="唯一编码" prop="code" label-width="100px">
          <el-input v-model="editForm.code" autocomplete="off" />
        </el-form-item>
        <el-form-item label="描述" prop="describe" label-width="100px">
          <el-input v-model="editForm.describe" autocomplete="off" />
        </el-form-item>
        <el-form-item label="状态" prop="statu" label-width="100px">
          <el-radio-group v-model="editForm.statu">
            <el-radio :label="0">禁用</el-radio>
            <el-radio :label="1">正常</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm(editFormRef)">
            立即创建
          </el-button>
          <el-button @click="resetForm(editFormRef)">重置</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>

    <!-- 权限分配弹窗 -->
    <el-dialog title="分配权限" v-model="permDialogVisible" width="600px">
      <!-- 表单提交分配的权限 -->
      <el-form :model="permForm" ref="permRef">
        <!-- 树形控件 props默认的节点的名字是什么 -->
        <!-- 树形结构本身选中 使用属性 ref -->
        <el-tree
          ref="treeRef"
          style="max-width: 600px"
          :data="permTreeData"
          show-checkbox
          node-key="id"
          default-expand-all
          :check-strictly="true"
          :props="defaultProps"
        >
        </el-tree>
      </el-form>
      <!-- 操作按钮 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="permDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitPermFormHandle(permForm)"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import {
  ElMessage,
  ElTable,
  FormInstance,
  FormRules,
  ElTree,
} from "element-plus";
import { ref, reactive, getCurrentInstance, onMounted } from "vue";
// 导入中文包
import zhCn from "element-plus/es/locale/lang/zh-cn";

/**权限分配 */
const permDialogVisible = ref(false);

// 用户权限修改时表单的数据
interface PermForm {
  id?: number;
  name?: string;
  code?: string;
  remark?: string;
  menuIds: [];
}
// 表单实例
const permForm = ref<PermForm>({
  id: 0,
  name: "",
  code: "",
  remark: "",
  menuIds: [],
});
const permRef = ref<FormInstance>();

// 菜单列表数据接口
interface PermTreeData {
  id: number;
  label: string;
  children?: PermTreeData[];
}
const defaultProps = {
  children: "children",
  label: "name", // 标签对应菜单中的name
};
// 定义树形结构数据
const permTreeData = ref<PermTreeData[]>([]);
//定义树形结构实体
const treeRef = ref<InstanceType<typeof ElTree>>();

// 请求后端菜单列表接口
const getMenuList = () => {
  proxy.$axios.get("/sys/menu/list").then((res: any) => {
    permTreeData.value = res.data.data;
  });
};

// 树形选择框中数据的回显
const permHandle = (id: number) => {
  // 显示弹窗
  permDialogVisible.value = true;
  // 请求后端获取数据
  proxy.$axios.get("/sys/role/info/" + id).then((res: any) => {
    // 设置选中的数据
    treeRef.value!.setCheckedKeys(res.data.data.menuIds, false);
    // 设置表单数据
    permForm.value = res.data.data;
  });
};

// 提交权限修改后的表单
const submitPermFormHandle = (item: PermForm) => {
  // 获取选中的数据
  var menusIds = treeRef.value!.getCheckedKeys(false);

  // 请求后端将数据载入数据库 传入参数和数据
  proxy.$axios
    .post("/sys/role/perm/" + permForm.value.id, menusIds)
    .then((res: any) => { 
      ElMessage({
        type: "success",
        message: res.data.data.msg,
        showClose: true,
        onClose: () => {
          // 关闭后刷新权限列表
          getRoleList();

        },
      });

      // 关闭弹窗
      permDialogVisible.value = false;
      // 重置表单
      resetForm(permRef.value);
    });
};

/**
 * 数据表格部分
 */
// 定义数据接口
interface TableData {
  id?: number;
  created?: string;
  updated?: string;
  statu: number;
  name: string;
  code: string;
  remark: string;
  menuIds: [];
}

// 定义表格和数据实例
const multipleTableRef = ref<InstanceType<typeof ElTable>>();
const multipleSelection = ref<TableData[]>([]); // 选中的数据

// 定义数据
const tableData = ref<TableData[]>([]);

const toggleSelection = (rows?: TableData[]) => {
  if (rows) {
    rows.forEach((row) => {
      // TODO: improvement typing when refactor table
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-expect-error
      multipleTableRef.value!.toggleRowSelection(row, undefined);
    });
  } else {
    multipleTableRef.value!.clearSelection();
  }
};
// 实现勾选后调用函数
const handleSelectionChange = (selectRows: TableData[]) => {
  multipleSelection.value = selectRows;
  // 如果选中的行数大于0 删除按钮起作用
  delBtuStatu.value = selectRows.length === 0 ? true : false;
};

/**
 * 行内表单部分
 */

// 定义数据接口
interface SearchForm {
  name?: string;
}
// 定义搜索框数据
const searchForm = reactive<SearchForm>({});
const searchFormRef = ref<FormInstance>(); // 创建表单引用实例
const delBtuStatu = ref(true); // 定义删除表单是否显示

/**
 * 分页组件部分
 */

// 分页组件
const total = ref(100);
const size = ref(10);
const current = ref(1);
const handleSizeChange = (val: number) => {
  size.value = val;
  // 重新获取表格数据
  getRoleList();
};

const handleCurrentChange = (val: number) => {
  current.value = val;
  // 重新获取表格数据
  getRoleList();
};

/**弹出式对话框 */

const centerDialogVisible = ref(false); // 定义弹出框是否显示
// 表单数据类型
interface EditForm {
  id?: number;
  name?: string;
  code?: string;
  describe?: string;
  statu?: number;
}

const formSize = ref("default"); // 表单尺寸
const editFormRef = ref<FormInstance>(); // 创建表单引用实例
const editForm = reactive<EditForm>({
  // 表单的默认数据
  name: "",
  describe: "",
  statu: 0,
});

// 表单验证规则
const rules = reactive<FormRules<EditForm>>({
  // 定义表单验证规则
  name: [{ required: true, message: "请输入名称", trigger: "blur" }],
  code: [{ required: true, message: "请输入权限编码", trigger: "blur" }],
  statu: [{ required: true, message: "请选择状态", trigger: "blur" }],
});

// 提交按钮
const submitForm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate((valid, fields) => {
    if (valid) {
      // 表单验证通过，提交表单数据
      proxy.$axios
        .post("/sys/role/" + (editForm.id ? "update" : "save"), editForm)
        .then((res: any) => {
          ElMessage({
            type: "success",
            message: res.data.msg, // 读取后端返回的信息
            duration: 1000, // 控制弹出时长
            onClose: () => {
              // 关闭弹窗后执行的回调函数 更新表格数据
              getRoleList();
            },
          });
        });
      // 关闭编辑窗口
      centerDialogVisible.value = false;
      // 清空表单数据
      resetForm(editFormRef.value);
    } else {
      // 表单验证失败
      return false;
    }
  });
};

// 表单重置
const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
};

// 弹窗关闭后操作
function handleClose() {
  // 取消弹窗显示
  centerDialogVisible.value = false;
  // 清除表单内容
  resetForm(editFormRef.value);
}

/**
 * 前端数据请求
 */

// 获取表格数据
const { proxy } = getCurrentInstance() as any; // 获取axios实例 proxy
function getRoleList() {
  proxy.$axios.get("/sys/role/list", {
      //请求时带给后端的参数
      params: {
        name: searchForm.name,
        current: current.value,
        size: size.value,
      },
    })
    .then((res: any) => {
      tableData.value = res.data.data.records;
      size.value = res.data.data.size;
      current.value = res.data.data.current;
      total.value = res.data.data.total;
    });
}

// 编辑按钮回显数据
const editHandle = (id: number) => {
  // 请求后端回显数据
  proxy.$axios.get("/sys/role/info/" + id).then((res: any) => {
    (editForm.code = res.data.data.code),
      (editForm.describe = res.data.data.describe),
      (editForm.name = res.data.data.name),
      (editForm.id = res.data.data.id),
      (editForm.statu = res.data.data.statu);

    // 回显并展示弹窗
    centerDialogVisible.value = true;
  });
};

// 删除按钮功能实现
const deleteHandle = (id: number | null) => {
  // 多选删除 id列表
  var ids: any[] = [];
  if (id) {
    // 单选一个 存在id
    ids.push(id);
  } else {
    // 多选框进行删除
    multipleSelection.value.forEach((row) => {
      ids.push(row.id);
    });
  }
  // 调用后端接口实现删除
  proxy.$axios.post("/sys/role/delete", ids).then((res: any) => {
    ElMessage({
      showClose: true,
      message: res.data.msg,
      type: "success",
      onClose: () => {
        //关闭后刷新列表
        getRoleList();
      },
    });
  });
};

// 在组件渲染结束后加载数据
onMounted(() => {
  getRoleList();
  getMenuList();
});
</script>

<style>
.demo-form-inline .el-button {
  margin-left: -20px;
}

/* 分页组件css */
.el-pagination {
  float: right;
  margin-top: 22px;
}
</style>
